%{
	#include "funcoes.h"
	#include "y.tab.h"
%}

/* Definicao das expressoes regulares */
DIG	[0-9]
ID	[a-zA-Z][a-z0-9A-Z]*
SPACE	[\t\r" "]
FLOAT_ERR	[a-zA-Z]*[0-9]*[a-z0-9A-Z]*"."+

%%

{DIG}+{FLOAT_ERR}+"."*	{ /* Numeros reais mal formados */
						if(coment > 0) continue; 
						else adderror(LEXICO, cat_yytext("Float mal formado", yytext), linhas);
						}

{DIG}*{ID}*"."+{DIG}*{ID}+	{ /* Numeros reais mal formados */
						if(coment > 0) continue; 
						else adderror(LEXICO, cat_yytext("Float mal formado", yytext), linhas);
						}

{DIG}+{FLOAT_ERR}+{FLOAT_ERR}+{DIG}*{ID}*"."*	{ /* Numeros reais mal formados */
						if(coment > 0) continue; 
						else adderror(LEXICO, cat_yytext("Float mal formado", yytext), linhas);
						}
						
{DIG}+"."{DIG}+	{ /* Numeros reais */
				if(coment > 0) continue;
				else {yylval.real_valor = atof(yytext); return NUM_REAL;}
				}

{DIG}+{ID}+	{ /* Numeros inteiros mal formados */
						if(coment > 0) continue; 
						else adderror(LEXICO, cat_yytext("Integer mal formado", yytext), linhas);
						}

{DIG}+	{ /* Numeros inteiros */
		if(coment > 0) continue; /* Se fizer parte de um comentário, ignora a string */
		else if(tamanho_int(yytext) == 0) adderror(LEXICO, cat_yytext("Integer muito grande", yytext), linhas);
		else{yylval.int_valor = atoi(yytext); return NUM_INT;}
		}

":="	{
		if(coment > 0) continue;
		else return ATRIB;
		}

"<>"	{
		if(coment > 0) continue;
		else return DIFER;
		}

"<="	{
		if(coment > 0) continue;
		else return MENOR_IGUAL;
		}

"<"		{
		if(coment > 0) continue;
		else return MENOR;
		}

">="	{
		if(coment > 0) continue;
		else return MAIOR_IGUAL;
		}

">"		{
		if(coment > 0) continue;
		else return MAIOR;
		}

"="		{
		if(coment > 0) continue;
		else return IGUAL;
		}

"+"		{
		if(coment > 0) continue;
		else return SOMA;
		}

"-"		{
		if(coment > 0) continue;
		else return SUB;
		}

"*"		{
		if(coment > 0) continue;
		else return MULT;
		}

"/"		{
		if(coment > 0) continue;
		else return DIV;
		}

","		{
		if(coment > 0) continue;
		else return VIRG;
		}

";"		{
		if(coment > 0) continue;
		else return PVIRG;
		}

"."		{
		if(coment > 0) continue;
		else return PONTO;
		}

":"		{
		if(coment > 0) continue;
		else return DPONTOS;
		}

"("		{
		if(coment > 0) continue;
		else return APAR;
		}

")"		{
		if(coment > 0) continue;
		else return FPAR;
		}

"{"		{ /* Abre comentario */
		coment = 1;
		}

"}"		{ /* Fecha comentario */
		if(coment == 1)		
			coment = 0;
		else {
			adderror(LEXICO, cat_yytext("Comentario nao aberto", yytext), linhas);
			coment = 0;
		}
		}
		
{ID}+	{ /* Identificador ou palavra reservada */
		if(coment > 0) continue;
		else if(tamanho_str(yytext) == 0) adderror(LEXICO, cat_yytext("ID muito grande", yytext), linhas);
		else if(busca_res(tabela_pal_res, yytext, hash(yytext))) {
      if(strcmp(yytext, "begin") == 0) return BGIN;
      else if(strcmp(yytext, "const") == 0) return CONST;
      else if(strcmp(yytext, "do") == 0) return DO;
      else if(strcmp(yytext, "else") == 0) return ELSE;
      else if(strcmp(yytext, "end") == 0) return END;
      else if(strcmp(yytext, "if") == 0) return IF;
      else if(strcmp(yytext, "integer") == 0) { yylval.tipo = 1; return INT; }
      else if(strcmp(yytext, "program") == 0) return PROGRAM;
      else if(strcmp(yytext, "procedure") == 0) return PROCEDURE;
      else if(strcmp(yytext, "real") == 0) { yylval.tipo = 2; return REAL; }
      else if(strcmp(yytext, "repeat") == 0) return REPEAT;
      else if(strcmp(yytext, "readln") == 0) return READLN;
      else if(strcmp(yytext, "then") == 0) return THEN;
      else if(strcmp(yytext, "until") == 0) return UNTIL;
      else if(strcmp(yytext, "var") == 0) return VAR;
      else if(strcmp(yytext, "while") == 0) return WHILE;
      else if(strcmp(yytext, "writeln") == 0) return WRITELN;
      else return (-1);
		} 
		else	
			{ yylval.nome = strdup(yytext); return IDENT; } 
		}

{SPACE}+	{ /* Espacos e caracteres a serem ignorados */ }

"\n"	{ /* Enter. incrementa o numero de linhas do programa */
		linhas++;
		}

.		{ /* Qualquer outro caractere */
		if(coment > 0) continue;
		else adderror(LEXICO, cat_yytext("Char desconhecido", yytext), linhas);
		}

<<EOF>> {
			if(coment > 0) adderror(LEXICO, "Comentario nao fechado", linhas);;
			yyterminate();
		}

%%
